#include "PcapDevice.h"
#include "PcapFilter.h"
#include "Logger.h"
#include "TimespecTimeval.h"
#include "pcap.h"

namespace pcpp
{

	IPcapDevice::~IPcapDevice()
	{}

	bool IPcapDevice::setFilter(std::string filterAsString)
	{
		PCPP_LOG_DEBUG("Filter to be set: '" << filterAsString << "'");
		if (!m_DeviceOpened)
		{
			PCPP_LOG_ERROR("Device not Opened!! cannot set filter");
			return false;
		}

		struct bpf_program prog;
		PCPP_LOG_DEBUG("Compiling the filter '" << filterAsString << "'");
		if (pcap_compile(m_PcapDescriptor, &prog, filterAsString.c_str(), 1, 0) < 0)
		{
			/*
			 * Print out appropriate text, followed by the error message
			 * generated by the packet capture library.
			 */
			PCPP_LOG_ERROR("Error compiling filter. Error message is: " << pcap_geterr(m_PcapDescriptor));
			return false;
		}

		PCPP_LOG_DEBUG("Setting the compiled filter");
		if (pcap_setfilter(m_PcapDescriptor, &prog) < 0)
		{
			/*
			 * Print out error. The format will be the prefix string,
			 * created above, followed by the error message that the packet
			 * capture library generates.
			 */
			PCPP_LOG_ERROR("Error setting a compiled filter. Error message is: " << pcap_geterr(m_PcapDescriptor));
			pcap_freecode(&prog);
			return false;
		}

		PCPP_LOG_DEBUG("Filter set successfully");

		pcap_freecode(&prog);

		return true;
	}

	bool IPcapDevice::clearFilter()
	{
		return setFilter("");
	}

	bool IPcapDevice::matchPacketWithFilter(GeneralFilter& filter, RawPacket* rawPacket)
	{
		return filter.matchPacketWithFilter(rawPacket);
	}

	std::string IPcapDevice::getPcapLibVersionInfo()
	{
		return std::string(pcap_lib_version());
	}

}  // namespace pcpp
